﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;

namespace Tradex.ComponentModel {
    
    /// <summary>
    /// The ObjectComposer is the Tradex interface to inversion of control.
    /// </summary>
    public sealed class ObjectComposer {

        private ObjectComposer() {
        }

        CompositionContainer _Composer = null;

        /// <summary>
        /// Initializes the CompositionContainer. This method can only be called once to set up the internal
        /// objects.
        /// </summary>
        public void Initialize(CompositionContainer composer) {
            if (_Composer != null) {
                throw new InvalidOperationException("can not initialize more than once");
            }
            Contract.EndContractBlock();
            _Composer = composer;
        }

        /// <summary>
        /// Gets an instance of a service.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetInstance<T>() where T : class {
            if (_Composer == null) {
                throw new InvalidOperationException("not initialized");
            }
            Contract.EndContractBlock();

            return default(T);
        }

        /// <summary>
        /// Composes the object passed in as parameter.
        /// </summary>
        /// <param name="targets"></param>
        public void Compose(params object [] targets) {
            if (_Composer == null) {
                throw new InvalidOperationException("not initialized");
            }
            Contract.EndContractBlock();
            _Composer.ComposeParts(targets);
        }

        /// <summary>
        /// Indicates whether the Composer has been initialized.
        /// </summary>
        public bool IsInitialized {
            get {
                return _Composer != null;
            }
        }

        static ObjectComposer() {
            Current = new ObjectComposer();
        }

        /// <summary>
        /// Gets the registered one instance of the CompositionContainer that is used to compose the application.
        /// </summary>
        public static ObjectComposer Current { get; private set; }


    }

}
